package main


import(
	"google.golang.org/grpc"
	wt "gitee.com/go_rpc_echo/wechat"
	"golang.org/x/net/context"
	"encoding/json"
	"github.com/gomodule/redigo/redis"
	ut "gitee.com/go_rpc_echo/util"
	"net"
	"net/http"
	"io/ioutil"
	"io"
	"bytes"
	"fmt"
	"mime/multipart"
	"log"
)

type Server struct {

}

//type WechatRpcServer interface {
//	GetAccessToken(context.Context, *WechatInfo) (*AccessToken, error)
//	Notice(context.Context, *NoticeRequest) (*NoticeResponse, error)
//}

func (this *Server) GetAccessToken(ctx context.Context, info *wt.WechatInfo) (*wt.AccessToken, error){
	redis_key := "wechat_access_token:"+info.Appid
	t:=wt.AccessToken{}
	redisConn, _ := redis.Dial("tcp", "127.0.0.1:6379")
	defer redisConn.Close()
	exists, _ := redis.Bool(redisConn.Do("EXISTS", redis_key))
	if exists{
		t.AccessToken,_ = redis.String(redisConn.Do("GET", redis_key))
		i,_ := redis.Int64(redisConn.Do("PTTL", redis_key))
		t.ExpiresIn = i/1000
	}else{
		s:=ut.CurlGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+info.Appid+"&secret="+info.Secret)
		json.Unmarshal([]byte(s),&t)
		redisConn.Do("SET", redis_key, t.AccessToken)
		redisConn.Do("EXPIRE", redis_key, t.ExpiresIn)
	}
	return &t,nil
}

func (this *Server) Notice(ctx context.Context, nr *wt.NoticeRequest)(*wt.NoticeResponse,error){
	at,_ :=this.GetAccessToken(ctx,nr.Info)
	context_struct:= struct {
		Value string `json:"value"`
		Color string `json:"color"`
	}{
		Value:nr.Title,
		Color:"#743a3a",
	}
	_c_bytes,_:=json.Marshal(context_struct)
	_context:=string(_c_bytes)

	msg:=ut.PostJson(`
 {
           "touser":"osBGPwQ5g9T1Qj7UU6mNSFxu3qM0",
           "template_id":"XbLeFlj6no2uaC4da9dbEYxscWWo5dYO2UCYXqNiJyY",
           "url":"`+nr.Url+`",
           "data":{
                   "title": {
                       "value":"`+nr.Title+`",
                       "color":"#743a3a"
                   },"time": {
                       "value":"`+nr.Time+`",
                       "color":"#0000ff"
                   },"content":`+_context+`
           }
 }
`,"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+at.AccessToken)
	m:= struct {
		ErrCode int32 `json:"errcode"`
		ErrMsg string `json:"errmsg"`
	}{}
	json.Unmarshal([]byte(msg),&m)
	return &wt.NoticeResponse{Code:m.ErrCode,Msg:m.ErrMsg},nil
}
func (this *Server) SendText(ctx context.Context, nr *wt.NoticeRequest)(*wt.NoticeResponse,error){
	at,_ :=this.GetAccessToken(ctx,nr.Info)
	msg:=ut.PostJson(`
{
    "touser":"`+nr.OpenId+`",
    "msgtype":"text",
    "text":
    {
         "content":"`+nr.Content+`"
    }
}
`,"https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+at.AccessToken)
	m:= struct {
		ErrCode int32 `json:"errcode"`
		ErrMsg string `json:"errmsg"`
	}{}
	json.Unmarshal([]byte(msg),&m)
	return &wt.NoticeResponse{Code:m.ErrCode,Msg:m.ErrMsg},nil
}

func (this *Server) GetMediaId(ctx context.Context,req *wt.GetMediaIdRequest)(*wt.GetMediaIdResponse,error){
	at,_ :=this.GetAccessToken(ctx , req.Info)


	// 创建表单文件
	// CreateFormFile 用来创建表单，第一个参数是字段名，第二个参数是文件名
	buf := new(bytes.Buffer)
	writer := multipart.NewWriter(buf)
	formFile, err := writer.CreateFormFile("media", "tmp.jpg")
	if err != nil {
		log.Fatalf("Create form file failed: %s\n", err)
	}
	imagPath := req.Url
	resp, _ := http.Get(imagPath)
	body, _ := ioutil.ReadAll(resp.Body)
	io.Copy(formFile, bytes.NewReader(body))
	if err != nil {
		log.Fatalf("Write to form file falied: %s\n", err)
	}
	// 发送表单
	contentType := writer.FormDataContentType()
	writer.Close() // 发送之前必须调用Close()以写入结尾行
	url := "https://api.weixin.qq.com/cgi-bin/media/upload?access_token="+at.AccessToken+"&type=image"

	res, err := http.Post(url, contentType, buf)
	if err != nil {
		log.Fatalf("Post failed: %s\n", err)
	}

	defer res.Body.Close()
	body, _ = ioutil.ReadAll(res.Body)

	fmt.Println(res)

	media:= struct {
		MediaId string `json:"media_id"`
	}{}
		json.Unmarshal(body,&media)
	fmt.Println(string(body))
	return &wt.GetMediaIdResponse{media.MediaId},nil
}


func main(){
	grpcServer := grpc.NewServer()
	wt.RegisterWechatRpcServer(grpcServer,&Server{})
	lis, _ := net.Listen("tcp", "0.0.0.0:10006")
	grpcServer.Serve(lis)
}